#include "mboard.h"
#include "mboard_private.h"
#include "gpio_hw.h"
#include "rcc.h"

/**
 * LED0: PF9， 低电平灯亮，红灯
 * LED1: PF10，低电平灯亮，绿灯
 */

static void mLedClockInit(void)
{
	/* 使能SOC_GPIOF时钟 */
	RCC_EnableAhb1(RCC_CLK_AHB1_GPIOF);
}

static void mLedGpioInit(void)
{
	uint32_t tmp32;

	/* 输出模式 */
	tmp32 = SOC_GPIOF.MODER;
	tmp32 &= ~GPIO_MODER_MASK(9);
	tmp32 &= ~GPIO_MODER_MASK(10);
	tmp32 |= GPIO_MODER_OUT(9);
	tmp32 |= GPIO_MODER_OUT(10);
	SOC_GPIOF.MODER = tmp32;

	/* 推挽输出 */
	tmp32 = SOC_GPIOF.OTYPER;
	tmp32 &= ~GPIO_OTYPER_MASK(9);
	tmp32 &= ~GPIO_OTYPER_MASK(10);
	tmp32 |= GPIO_OTYPER_PP(9);
	tmp32 |= GPIO_OTYPER_PP(10);
	SOC_GPIOF.OTYPER = tmp32;

	/* 2M的的输出速度 */
	tmp32 = SOC_GPIOF.OSPEEDR;
	tmp32 &= ~GPIO_OSPEEDR_MASK(9);
	tmp32 &= ~GPIO_OSPEEDR_MASK(10);
	tmp32 |= GPIO_OSPEEDR_2M(9);
	tmp32 |= GPIO_OSPEEDR_2M(10);
	SOC_GPIOF.OSPEEDR = tmp32;

	/* 禁用上下拉 */
	tmp32 = SOC_GPIOF.PUPDR;
	tmp32 &= ~GPIO_PUPDR_MASK(9);
	tmp32 &= ~GPIO_PUPDR_MASK(10);
	tmp32 |= GPIO_PUPDR_NONE(9);
	tmp32 |= GPIO_PUPDR_NONE(10);
	SOC_GPIOF.PUPDR = tmp32;

	/* 输出为高，LED熄灭 */
	SOC_GPIOF.BSRR = GPIO_BSRR_SET(9) | GPIO_BSRR_SET(10);
}

void mLedInit(void)
{
	mLedClockInit();
	mLedGpioInit();
}

void mLedSet(MLedColor_e color, MLedState_e state)
{
	switch (state) {
		case MLED_STATE_OFF:
			/* 输出高电平 */
			SOC_GPIOF.BSRR = (uint32_t)color;
			break;
		case MLED_STATE_ON:
			/* 输出低电平 */
			SOC_GPIOF.BSRR = (uint32_t)color << 16;
			break;
		case MLED_STATE_TOGGLE:
			uint32_t val = SOC_GPIOF.ODR;
			SOC_GPIOF.BSRR = ((val & (uint32_t)color) << 16) |
			                 ((~val) & (uint32_t)color);
			break;
	}
}

void mLedTest(void)
{
	uint32_t count;

	count = 10;
	while (count--) {
		mBoardDelayMs(200);
		mLedSet(MLED_COLOR_ALL, MLED_STATE_ON);
		mBoardDelayMs(500);
		mLedSet(MLED_COLOR_ALL, MLED_STATE_OFF);
	}
	count = 10;
	while (count--) {
		mBoardDelayMs(500);
		mLedSet(MLED_COLOR_ALL, MLED_STATE_TOGGLE);
	}
}
